package com.citycloud.datac.client.filter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import com.citycloud.datac.client.client.DataCOauth2Client;
import com.citycloud.datac.client.constants.DataCClientConstant;
import com.citycloud.datac.client.dto.DetailedUserInfo;
import com.citycloud.datac.client.resoult.JsonResoult;

import lombok.extern.slf4j.Slf4j;

/***
 * @className AuthorizationFilter
 * @author wangyj
 * @Date 2019/9/16 20:28
 * @description
 */
@Slf4j
public class Oauth2AuthorizationFilter implements Filter {
	private static String TOKEN = "token";
	private static String ACCESS_TOKEN = "access_token";
	@Autowired(required = false)
	private DataCOauth2Client oauth2Client;
	@Autowired(required = false)
	private HttpSession session;
	private static List<String> excludedList = new ArrayList<>();

	private static final String STR_EXCLUDEDURI = "excludedUri";
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		if (StringUtils.isNotBlank(filterConfig.getInitParameter(STR_EXCLUDEDURI))) {
            excludedList.addAll(Arrays.stream(filterConfig.getInitParameter(STR_EXCLUDEDURI).split(",")).distinct()
                    .collect(Collectors.toList()));
        }
	}

	@Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
			throws IOException, ServletException {
		// 将请求转换成HttpServletRequest 请求
		log.info("进入datac-client-filter:{}");
		HttpServletRequest req = (HttpServletRequest) servletRequest;
		List<String> exclude = excludedList.parallelStream()
				.filter(s -> (StringUtils.isNotBlank(req.getContextPath())
						? req.getRequestURI().replaceAll(req.getContextPath(), "")
						: req.getRequestURI()).startsWith(s))
				.collect(Collectors.toList());
		if (!CollectionUtils.isEmpty(exclude)) {
			filterChain.doFilter(servletRequest, servletResponse);
			return;
		}
		// 站点id
		Long projectId = null;
		// 获取token
		String accessToken = null;
		try {
			accessToken = StringUtils.isEmpty(req.getParameter(TOKEN)) ? req.getParameter(ACCESS_TOKEN)
					: req.getParameter(TOKEN);
			if (StringUtils.isEmpty(accessToken)) {
				accessToken = StringUtils.isEmpty(req.getHeader(TOKEN)) ? req.getHeader(ACCESS_TOKEN)
						: req.getHeader(TOKEN);
			}
			log.info("进行datac-filter -------accessToken:{}", accessToken);
			if (StringUtils.isEmpty(accessToken)) {
				JsonResoult.putResponse(servletRequest, servletResponse, -1L, "token不存在", oauth2Client.logout());
				return;
			}
			DetailedUserInfo qcloudUser = oauth2Client.getUserInfo(accessToken);
			projectId = qcloudUser.getCurrentSiteId();
			setAttributes(projectId, accessToken, qcloudUser);
			((HttpServletResponse) servletResponse).setHeader(TOKEN, accessToken);
			filterChain.doFilter(servletRequest, servletResponse);
		} catch (Exception e) {
//            filterChain.doFilter(servletRequest, servletResponse);
			log.error("-----接入token出现问题---message:{}", e.getMessage());
			JsonResoult.putResponse(servletRequest, servletResponse, -2L, e.getMessage(), oauth2Client.logout());
			return;
		}
	}

	@Override
	public void destroy() {
	}

	private void setAttributes(Long projectId, String accessToken, DetailedUserInfo qcloudUser) {
		session.setAttribute(DataCClientConstant.SESSION_CURRENT_SITE_ID, projectId);
		session.setAttribute(DataCClientConstant.SESSION_TOKEN, accessToken);
		session.setAttribute(DataCClientConstant.SESSION_USER, qcloudUser);
		session.setAttribute(DataCClientConstant.SESSION_PLATFORM_SITE,
				qcloudUser != null ? qcloudUser.getPlatformId() : null);
		session.setAttribute(DataCClientConstant.SESSION_IS_PLATFORM_SITE,
				qcloudUser != null && qcloudUser.getPlatformId().equals(projectId));
	}
}
